﻿#ifndef IM_Socket_Server_h__
#define IM_Socket_Server_h__

#define _DEBUG

#include "Log.h"

#include<thread>

#include "IM_Epoll.h"
#include "Pri_Socket.h"
const int MAX_INFO = 128;
const int  MAX_EVENT = 64;
const int MAX_SOCKET =1024;   
#include <vector>


class Pri_Socket;

struct IM_SocketMessage
{
	int  type;
	int  socket_id;
	int   ud;
	char * buffer;
};

struct SocketMessage
{
	int socket_id;
	unsigned int context_handle;
	int ud;
	char * data;

	SocketMessage() {}

	SocketMessage(int socket_id, unsigned int context_handle, int ud, char *data) {
		socket_id = socket_id;
		context_handle = context_handle;
		ud = ud;
		data = data;
	}

	SocketMessage(const SocketMessage & other)
	{
		socket_id = other.socket_id;
		context_handle = other.context_handle;
		ud = other.ud;
		data = other.data;
	}
	
};

struct SocketServerMessage 
{
	int type;
	int socket_id;
	int ud;
	char *buffer;
};

const int SOCKET_CLOSE = 0;
const int SOCKET_ERR = 1;
const int SOCKET_ACCEPT = 2;
const int SOCKET_DATA = 3;
const int SOCKET_OPEN = 4;

struct  RequestOpen
{
	int id;
	int port;
	unsigned int handle;
	char host[1];
};
struct RequestListen
{
	int id;
	int fd;
	uintptr_t handle;
	char host[1];
};

struct Request_send
{
	int id;
	int size;
	char * buffer;
};

struct  RequestPackage
{
	uint8_t header[8];
	union
	{
		char buffer[256];

		RequestOpen open;
		RequestListen listen;
		Request_send send;
	}u;
	uint8_t dummy[256];
};

class IM_Socket_Server
{
public:
	IM_Socket_Server();
	~IM_Socket_Server();

	bool socket_server_start();
	void socket_server_close();

	//发送数据  
	bool socket_server_send(int socket_id,const char* buffer,int size);
	
	//监听一个socket  返回 其 id 
	int sokcet_server_listen(unsigned int handle,const char *addr,int port,int backlog);
private:
	bool init();

	void _socket_thread_proc();
	int _socket_poll();
	int _socket_server_poll(SocketMessage& result,int &more);

	//检查有没有请求需要处理 
	bool _has_request();
	//处理请求
	int  _handler_request(SocketMessage & result);
	void _send_request(RequestPackage & request,char type,int len);

	int  _socket_send(Request_send *request,SocketMessage & result);
	int  _socket_listen(RequestListen * request, SocketMessage & result);

	void _clear_closed_event(SocketMessage&result,int type);
	int _report_connect(Pri_Socket * s, SocketMessage & result);
	int _report_accept(Pri_Socket * s, SocketMessage & result);
	int _forwar_message_tcp(Pri_Socket *s, SocketMessage &result);

	void _force_close(Pri_Socket * s, SocketMessage & result);
private:
	Pri_Socket * create_sokcet(unsigned int context_handle, int protocol, int socket_fd,bool add);
	Pri_Socket * create_sokcet(int socket_id,unsigned int context_handle, int protocol, int socket_fd, bool add);
	int reserve_id();
private:
	int m_pip_write_fd;
	int m_pip_read_fd;
	bool m_check_request;
	fd_set m_rfds;

	IM_Epoll * m_epoll;
	int m_alloc_id;
	int m_event_count;
	int m_event_index;
	IM_Epoll::EpollEvent m_events[MAX_EVENT];

	Pri_Socket * m_sockets[MAX_SOCKET];

	std::thread * m_thread;

	std::mutex  m_mutex;
};

#endif // IM_Socket_Server_h__


